//
//  UIView+ZGradient.swift
//  AGF
//
//  Created by CS001 on 2021/3/15.
//

import UIKit
import BWToolKit
import SwifterSwift

extension UIView {
    private struct AKeys{
        static var zGrEnabled = "zGrEnabled"
        static var zGrStartPoint = "zGrStartPoint"
        static var zGrEndPoint = "zGrEndPoint"
        static var zGrLocations = "zGrLocations"
        static var zGrColors = "zGrColors"
        static var zGradientLayer = "zGradientLayer"
    }
    
    @objc public static func setupZGradientLoad() {
        let cls = Self.self
        Objcer.swizzleSelector1(#selector(awakeFromNib), inClass1: cls, withSelector2: #selector(sGrAwakeFromNib), inClass2: cls)
        Objcer.swizzleSelector1(#selector(layoutSubviews), inClass1: cls, withSelector2: #selector(sGrLayoutSubviews), inClass2: cls)
    }
    
    private func buildGradient(){
        /// 解析数据
        guard zGrEnabled else {
            return
        }
        var colors: [UIColor] = []
        if (!zGrColors.isEmpty)
        {
            let comps = zGrColors.replacingOccurrences(of: "#", with: "0x").components(separatedBy: ",")
            for str in comps {
                let colorComps = str.components(separatedBy: ".")
                var color: UIColor!
                
                guard let colorStr = colorComps.first else {
                    continue
                }
                color = UIColor(hexString: colorStr)
                
                if colorComps.count == 2,
                   let alphaStr = colorComps.last,
                   let alpha = Float(alphaStr) {
                    color = color.withAlphaComponent(CGFloat(alpha))
                }
                colors.append(color)
            }
        }
        
        var locations: [NSNumber] = []
        if !zGrLocations.isEmpty {
            let comps = zGrLocations.components(separatedBy: ",")
            locations = comps.compactMap{ NSNumber(value: Float($0) ?? 0) }
        }
        
        let layer = CAGradientLayer()
        layer.startPoint = zGrStartPoint
        layer.endPoint = zGrEndPoint
        layer.locations = locations
        layer.colors = colors.map{ $0.cgColor }
        layer.frame = bounds
        layer.cornerRadius = self.layer.cornerRadius
        zGradientLayer = layer
    }
    
    @objc func sGrAwakeFromNib(){
        sGrAwakeFromNib()
        
        buildGradient()
    }
    
    @objc private func sGrLayoutSubviews(){
        sGrLayoutSubviews()
        
        if zGrEnabled, let glayer = zGradientLayer {
            glayer.frame = bounds
            layer.insertSublayer(glayer, at: 0)
        }
    }
    
    public func setupZGradient(
        startPoint: CGPoint = .init(x: 0, y: 0),
        endPoint: CGPoint = .init(x: 0, y: 1),
        locationAndColors: [CGFloat: UIColor]
    ){
        zGrEnabled = true
        zGrStartPoint = startPoint
        zGrEndPoint = endPoint
        let sorted = locationAndColors.sorted(by: \.key)
        zGrLocations = sorted.map{ "\($0.key)" }.joined(separator: ",")
        zGrColors = sorted.map{ $0.value.hexString }.joined(separator: ",")
        
        buildGradient()
    }
    
    /// 是否开启渐变
    @IBInspectable var zGrEnabled: Bool {
        get{
            return Objcer.getASValue(for: self, key: &AKeys.zGrEnabled) as? Bool ?? false
        }
        set{
            Objcer.setASValue(newValue, for: self, key: &AKeys.zGrEnabled, policy: .assign)
        }
    }
    /// 渐变开始点
    @IBInspectable var zGrStartPoint: CGPoint{
        get{
            let v = Objcer.getASValue(for: self, key: &AKeys.zGrStartPoint) as! String
            return NSCoder.cgPoint(for: v)
        }
        set{
            Objcer.setASValue(NSCoder.string(for: newValue), for: self, key: &AKeys.zGrStartPoint, policy: .copy)
        }
    }
    /// 渐变结束点
    @IBInspectable var zGrEndPoint: CGPoint{
        get{
            let v = Objcer.getASValue(for: self, key: &AKeys.zGrEndPoint) as! String
            return NSCoder.cgPoint(for: v)
        }
        set{
            Objcer.setASValue(NSCoder.string(for: newValue), for: self, key: &AKeys.zGrEndPoint, policy: .copy)
        }
    }
    /// 渐变色点: @"0,1.0"
    @IBInspectable var zGrLocations: String{
        get{
            return Objcer.getASValue(for: self, key: &AKeys.zGrLocations) as! String
        }
        set{
            Objcer.setASValue(newValue, for: self, key: &AKeys.zGrLocations, policy: .copy)
        }
    }
    /// 渐变色: @"0xff0000.60,0xff0011.0"，`.`后面的值表示alpha值0~100
    @IBInspectable var zGrColors: String{
        get{
            return Objcer.getASValue(for: self, key: &AKeys.zGrColors) as! String
        }
        set{
            Objcer.setASValue(newValue, for: self, key: &AKeys.zGrColors, policy: .copy)
        }
    }
    /// 渐变背景层
    var zGradientLayer: CAGradientLayer? {
        get{
            return Objcer.getASValue(for: self, key: &AKeys.zGradientLayer) as? CAGradientLayer
        }
        set{
            if let v = newValue {
                Objcer.setASValue(v, for: self, key: &AKeys.zGradientLayer, policy: .retain)
            }
        }
    }
}

